home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
raytrace
/
pov
/
gen
/
animdat
/
symtab.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-22
|
5KB
|
199 lines
/*--------------------------------------------------------------*/
/* ANIMDAT 1.1 */
/* copyright 1992 - TODD SANKEY */
/* */
/* The author hereby grants permission for the use and sharing */
/* of both source code end executable versions of this software */
/* at no charge. This software is not for sale and no other */
/* shall charge for it without the expressed consent of the */
/* author. */
/* */
/* The source code can be freely modified, but it must retain */
/* the original copyright notice, and the author must be */
/* notified of these changes if the altered code is to be */
/* distributed. */
/*--------------------------------------------------------------*/
/*------------------------------------------------------*/
/* symtab.c Routines for interfacing to a symbol */
/* table organized as a binary tree. */
/*------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include "common.h"
/*------------------------------------------------------*/
/* alloc_symbol Allocate a symbol node. */
/*------------------------------------------------------*/
static sym_ptr alloc_symbol()
{
sym_ptr sp;
sp = (sym_ptr)malloc(sizeof(sym));
if (sp == NULL)
error(FAILED_MALLOC,NULL);
sp->left = NULL;
sp->right = NULL;
sp->name = NULL;
sp->sym_info = NULL;
return (sp);
}
/*------------------------------------------------------*/
/* search_symtab Search a symbol table for a */
/* named symbol. */
/*------------------------------------------------------*/
sym_ptr search_symtab(sym_ptr symtab, char *name)
{
int comp;
if (symtab!=NULL)
do {
comp=strcmp(name,symtab->name);
if (comp < 0)
symtab = symtab->left;
else if (comp > 0)
symtab = symtab->right;
} while (comp && symtab!=NULL);
return (symtab);
}
/*------------------------------------------------------*/
/* add_symbol Add a symbol to a symbol table */
/* provided an equivalently named */
/* symbol does not already exist. */
/*------------------------------------------------------*/
sym_ptr add_symbol(sym_ptr *symtab, char *name)
{
sym_ptr sp,osp;
int comp;
if ((*symtab) == NULL) {
*symtab = alloc_symbol();
sp = (*symtab);
}
else {
sp = (*symtab);
do {
comp=strcmp(name,sp->name);
osp = sp;
if (comp < 0)
sp = sp->left;
else if (comp > 0)
sp = sp->right;
} while (comp && (sp != NULL) );
if (comp < 0) {
osp->left = alloc_symbol();
sp = osp->left;
}
else if (comp > 0) {
osp->right = alloc_symbol();
sp = osp->right;
}
else
error(SYMBOL_REDEFINED,name);
}
sp->name = (char *)malloc(strlen(name)+1);
strcpy(sp->name,name);
return (sp);
}
/*------------------------------------------------------*/
/* traverse_symtab Call a function once for each */
/* node in a symbol table. */
/*------------------------------------------------------*/
void traverse_symtab(sym_ptr symtab,void (*f)(sym_ptr symbol))
{
if (symtab != NULL) {
traverse_symtab(symtab->left,f);
(*f)(symtab);
traverse_symtab(symtab->right,f);
}
}
/*------------------------------------------------------*/
/* display_symbol Display a symbol's name. */
/*------------------------------------------------------*/
static void display_symbol(sym_ptr symbol)
{
printf(" %s",symbol->name);
}
/*------------------------------------------------------*/
/* display_symtab Display every name in a symbol */
/* table. */
/*------------------------------------------------------*/
void display_symtab(sym_ptr symtab)
{
traverse_symtab(symtab,display_symbol);
}
/*------------------------------------------------------*/
/* eval_symbol Evaluate a mathematical symbol. */
/*------------------------------------------------------*/
double eval_symbol(char *name)
{
sym_ptr symbol;
symbol = search_symtab(symbol_table,name);
if (symbol == NULL)
error(UNDEFINED_SYMBOL,name);
if (!symbol->update_flag) {
symbol->update_flag = 1;
switch (symbol->sym_type) {
case SYM_DOUBLE :
symbol->cur_val = eval_btree((btree_node_ptr)(symbol->sym_info));
break;
case SYM_FILE :
fscanf((FILE *)symbol->sym_info,"%lf",&(symbol->cur_val));
break;
default :
sprintf(cur_line,"Symbol -%s- could not be evaluated numerically",name);
error(SYNTAX_ERROR,cur_line);
}
}
return (symbol->cur_val);
}
/*------------------------------------------------------*/
/* print_symbol Print the value for a symbol */
/* of any type. */
/*------------------------------------------------------*/
void print_symbol(FILE *ofile,char *name)
{
sym_ptr symbol;
symbol = search_symtab(symbol_table, name);
if (symbol == NULL)
error(UNDEFINED_SYMBOL, name);
switch (symbol->sym_type) {
case SYM_DOUBLE:
case SYM_FILE:
fprintf(ofile,"%lf",eval_symbol(name));
break;
case SYM_STRING:
fprintf(ofile,"%s",(char *)symbol->sym_info);
break;
default:
error(SYNTAX_ERROR,"Bad symbol type");
}
}